home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
C/C++ Users Group Library 1996 July
/
C-C++ Users Group Library July 1996.iso
/
listings
/
v_10_02
/
1002060a
< prev
next >
Wrap
Text File
|
1991-12-11
|
11KB
|
464 lines
/***********************************************
*
* file d:\lsu\cujhuff2.c
*
**********************************************/
#include "d:\lsu\cujhuff.h"
/*
create_huffman_code(item_array)
This routine is the top of the routines that create
the codes. Create the codes xxxxx010 for the characters
read in. You use the item_array which contains the
counts of occurances and so on.
*/
create_huffman_code(item_array)
struct item_struct item_array[];
{
int counter,
i,
not_ended;
struct item_struct temp;
sort_item_array(item_array);
disable_zero_counts(item_array);
/***********************************
*
* The following short loop is the
* heart of the algorithm. The
* rest is the implementation detail
* which is not trivial.
*
*************************************/
counter = 0;
not_ended = 1;
while(not_ended){
if( (counter % 50) == 0) printf("\n> Creating code ");
printf(".");
combine_and_code_2_smallest_items(item_array, ¬_ended);
sort_item_array(item_array);
counter++;
} /* ends while not_ended */
reverse_order_of_coded(item_array);
} /* ends create_huffman_code */
/*
sort_item_array(item_array)
This is a very simple bubble sort algorithm.
It does use the Microsoft C ability to
set one struct equal to another. Some
compilers do not support this.
*/
sort_item_array(item_array)
struct item_struct item_array[];
{
int i,
not_finished,
swapped;
struct item_struct temp;
not_finished = 1;
while(not_finished){
swapped = 0;
for(i=0; i<LENGTH-1; i++){
if(item_array[i].count < item_array[i+1].count){
swapped = 1;
temp = item_array[i];
item_array[i] = item_array[i+1];
item_array[i+1] = temp;
} /* ends if you need to swap */
} /* ends loop over i */
if(swapped == 0)
not_finished = 0;
} /* ends while not_finished */
/* Perform an extra pass through the sort to
ensure all 'D'isbaled items are below all
'E'nabled items in the item_array */
not_finished = 1;
while(not_finished){
swapped = 0;
for(i=0; i<LENGTH-1; i++){
if( (item_array[i].indicator == 'D') &&
(item_array[i+1].indicator == 'E')){
swapped = 1;
temp = item_array[i];
item_array[i] = item_array[i+1];
item_array[i+1] = temp;
} /* ends if you need to swap */
} /* ends loop over i */
if(swapped == 0)
not_finished = 0;
} /* ends while not_finished */
} /* ends sort_item_array */
/*
disable_zero_counts(item_array)
You do not want to work on the characters
that were not in the input file so you
disable them.
*/
disable_zero_counts(item_array)
struct item_struct item_array[];
{
int i;
for(i=0; i<LENGTH; i++){
if(item_array[i].count == 0)
item_array[i].indicator = 'D';
} /* ends loop over i */
} /* ends disable_zero_counts */
/*
combine_and_code_2_smallest_items(item_array, not_ended)
This function calls other functions to find the two
smallest items and then combine or link them.
*/
combine_and_code_2_smallest_items(item_array, not_ended)
struct item_struct item_array[];
int *not_ended;
{
char r[80];
int next_smallest, smallest;
find_smallest_item(item_array, &smallest);
if(smallest <= 0){
*not_ended = 0;
}
else{
next_smallest = smallest;
find_next_smallest_item(item_array, &next_smallest);
code_2_smallest_items(item_array, smallest, next_smallest);
combine_2_smallest_items(item_array, smallest,
next_smallest);
}
} /* ends combine_and_code_2_smallest_items */
/*
find_smallest_item(item_array, smallest)
You are working with a sorted item_array
so you start looking at the bottom of the
array. You look until you find the first
'E'nabled indicator then you stop.
*/
find_smallest_item(item_array, smallest)
struct item_struct item_array[];
int *smallest;
{
int i,
searching;
*smallest = 0;
searching = 1;
i = 255;
while(searching){
if(item_array[i].indicator == 'E'){
*smallest = i;
searching = 0;
} /* ends if indicator == 'E' */
else{
i = i-1;
if(i<0){
*smallest = -1;
searching = 0;
}
} /* ends else indicator != 'E' */
} /* ends while searching */
} /* ends find_smallest_item */
/*
find_next_smallest_item(item_array, next_smallest)
You are working with a sorted item_array
so you start looking at the smallest item of the
array. You look until you find the first
'E'nabled indicator then you stop.
*/
find_next_smallest_item(item_array, next_smallest)
struct item_struct item_array[];
int *next_smallest;
{
int i,
searching;
searching = 1;
i = *next_smallest-1;
while(searching){
if(item_array[i].indicator == 'E'){
*next_smallest = i;
searching = 0;
} /* ends if indicator == 'E' */
else{
i = i-1;
if(i<0){
*next_smallest = -1;
searching = 0;
}
} /* ends else indicator != 'E' */
} /* ends while searching */
} /* ends find_next_smallest_item */
/*
combine_2_smallest_items(...
. add the two counts together
. disable the smallest one
. link the smallest one to the next smallest one
*/
combine_2_smallest_items(item_array, smallest, next_smallest)
struct item_struct item_array[];
int next_smallest, smallest;
{
int i, not_finished;
item_array[next_smallest].count = item_array[smallest].count
+
item_array[next_smallest].count;
item_array[smallest].count = item_array[next_smallest].count;
item_array[smallest].indicator = 'D';
i = 0;
not_finished = 1;
while(not_finished){
if(item_array[next_smallest].includes[i] == 256){
item_array[next_smallest].includes[i] = smallest;
not_finished = 0;
}
else{
i++;
if(i > LLENGTH){
printf("\n\n> Ran out of links\n\n");
exit(1);
}
}
} /* ends while not_finished */
} /* ends combine_2_smallest_items */
/*
code_2_smallest_items(...
The smallest item is coded with a ONE
The next smallest item is coded with a ZERO
*/
code_2_smallest_items(item_array, smallest, next_smallest)
struct item_struct item_array[];
int next_smallest, smallest;
{
code_smallest_item(item_array, smallest);
code_next_smallest_item(item_array, next_smallest);
} /* code_2_smallest_items */
/*
code_smallest_item(item_array, smallest)
You must code the item as well as
all the other items included with it
on down to the end.
Set the code to ONE.
*/
code_smallest_item(item_array, smallest)
struct item_struct item_array[];
short smallest;
{
int i,
j,